﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.ComponentModel;
using System.Data.SqlClient;
using System.Reflection;

namespace Inventory
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class Window1 : Window
    {
        //private InventoryDataContext _context = new InventoryDataContext(WpfApplication1.Properties.Settings.Default.SalesManagerConnectionString);
        private SalesManagerEntities _context = new SalesManagerEntities();
        private SalesManagerCodes _contextCodes = new SalesManagerCodes();
        private CollectionViewSource _productGroupViewSource;// = new CollectionViewSource();
        private CollectionViewSource _productViewSource;
        private CollectionViewSource _productComponentViewSource;
        private CollectionViewSource _productOrderSourceViewSource;
        private CollectionViewSource _isAProductListViewSource;
        private CollectionViewSource _resultantProductPricing;
        private CollectionViewSource _productInventory;
        private CollectionViewSource _productInventoryUnmappedLocations;
        public int OwnerID;
        private CollectionViewSource _detailViewSource = new CollectionViewSource();

        public Window1()
        {
            InitializeComponent();
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            if (App.Args.Count() == 0)
            {
                MessageBox.Show("No OwnerID specified");
                Close();
                return;
            }
            if (!int.TryParse(App.Args[0], out OwnerID))
            {
                MessageBox.Show("Invalid OwnerID specified");
                Close();
                return;
            }
            _context.ContextOptions.LazyLoadingEnabled = true;
            _productGroupViewSource = (CollectionViewSource)FindResource("ProductGroup");
            _productGroupViewSource.Source = from c in _context.tblProductGroup
                                                 .Include("Products.ProductComponents.ComponentProduct")
                                                 .Include("Products.ProductPricing")
                                                 //.Include("Products.Inventory.Location")
                                             where c.Active 
                                                && c.Owner.OwnerID == OwnerID
                                             orderby c.ShortName
                                             select c;
                                             //select new {c.ProductGroupID, c.ShortName, c.Products};
            _productGroupViewSource.View.CurrentChanged += new EventHandler(ProductGroup_CurrentChanged);

            ((CollectionViewSource)FindResource("ProductGroup2")).Source = from c in _context.tblProductGroup
                                                                           where c.Owner.OwnerID == OwnerID
                                                                           orderby c.ShortName
                                                                           select c;

            _productViewSource = (CollectionViewSource)FindResource("Products");

            _resultantProductPricing = (CollectionViewSource)FindResource("ResultantProductPricing");
            _productInventory = (CollectionViewSource)FindResource("ProductInventory");
            _productInventoryUnmappedLocations = (CollectionViewSource)FindResource("ProductInventoryUnmappedLocations");

            // Build the pricing class selection list with a null value added in
            var pricingClassList = (from c in _contextCodes.codeProductPricingClass
                                    where c.OwnerID == OwnerID
                                    select new { ProductPricingClassCode = c.ProductPricingClassCode, c.Description }).ToList();
            ((CollectionViewSource)FindResource("PricingCodes")).Source = pricingClassList;

            // Build the promotion selection list with a null value added in.
            ((CollectionViewSource)FindResource("PromotionList")).Source = (from c in _contextCodes.tblPromotion
                                                                            where c.OwnerID == OwnerID
                                                                                && c.Active
                                                                            select c);

            _isAProductListViewSource = (CollectionViewSource)FindResource("IsAProductList");
            ProductGroup_CurrentChanged(null, null);
            if (_productViewSource.View != null)
                Product_CurrentChanged(null, null);

            _productComponentViewSource = (CollectionViewSource)FindResource("ProductComponents");

            // Initialize the Misc tab
            var miscLines = from c in _context.tblMiscDef
                            where c.TableName == "tblProduct" &&
                                (c.Owner.OwnerID == null || c.Owner.OwnerID == OwnerID)
                            select new { c.Name, c.Tooltip, c.FieldNumber };
            int miscCt = 0;
            foreach (var item in miscLines)
            {
                GridMisc.RowDefinitions.Add(new RowDefinition());
                Label lbl = new Label();
                lbl.Content = item.Name;
                lbl.ToolTip = item.Tooltip;
                GridMisc.Children.Add(lbl);
                Grid.SetRow(lbl, miscCt);
                Grid.SetColumn(lbl, 0);

                TextBox tb = new TextBox();
                Binding b = new Binding("UserDefined" + item.FieldNumber.ToString());
                tb.SetBinding(TextBox.TextProperty, b);
                GridMisc.Children.Add(tb);
                Grid.SetRow(tb, miscCt);
                Grid.SetColumn(tb, 1);

                miscCt++;
            }

            // Initialize the source for the OrderSource drop down.
            ((CollectionViewSource)FindResource("OrderSources")).Source = 
                (from c in _context.tblOrderSource where c.OwnerID == OwnerID select c );
            _productOrderSourceViewSource = (CollectionViewSource)FindResource("ProductOrderSource");
        }

        void Product_CurrentChanged(object sender, EventArgs e)
        {
            if (_productViewSource.View.CurrentItem != null)
            {
                tblProduct product = (tblProduct)_productViewSource.View.CurrentItem;

                // Load the resulting product pricing for the selected product
                SqlConnection conn = (SqlConnection)((System.Data.EntityClient.EntityConnection)_context.Connection).StoreConnection;

                if (conn.State != System.Data.ConnectionState.Open)
                    conn.Open();
                SqlCommand cmm = conn.CreateCommand();
                cmm.CommandText = "exec spProductPricing " + product.ProductID.ToString() + ", null, null";
                cmm.CommandType = System.Data.CommandType.Text;
                System.Data.DataSet ds = new System.Data.DataSet();
                SqlDataAdapter da = new System.Data.SqlClient.SqlDataAdapter(cmm);
                da.Fill(ds);

                _resultantProductPricing.Source = ds.Tables[0];

                // Load the available locations
                _productInventoryUnmappedLocations.Source =
                    (from c in _context.tblLocation
                    select c).Except(from c in _context.tblLocation where c.Inventory.Any(i=>i.Product.ProductID==product.ProductID) select c);

                //product.SequenceStepProducts.Load();
            }
        }

        void ProductGroup_CurrentChanged(object sender, EventArgs e)
        {
            //int productGroupID = (int)_productGroupViewSource.View.CurrentItem.GetType().GetProperties()[0].GetValue(_productGroupViewSource.View.CurrentItem, null);
            if (comboProductGroup.SelectedValue != null)
            {
                int productGroupID = (int)comboProductGroup.SelectedValue;
                var isAProductList = (from c in _context.tblProduct
                                      where (bool)c.ActiveItem && !(bool)c.SalableItem && !(bool)c.InventoryItem && c.ProductGroup.ProductGroupID == productGroupID
                                      orderby c.ShortName
                                      select new { ProductID = (int?)c.ProductID, ShortName = c.ShortName }).ToList();
                isAProductList.Add(new { ProductID = (int?)null, ShortName = "" });
                _isAProductListViewSource.Source = isAProductList;

                _productViewSource.Source = (from c in _context.tblProduct
                                             where c.ProductGroupID == productGroupID
                                                && (!(bool)chkFilterActive.IsChecked || (bool)c.ActiveItem)
                                             select c).ToList();

                _productViewSource.View.CurrentChanged -= new EventHandler(Product_CurrentChanged);
                _productViewSource.View.CurrentChanged += new EventHandler(Product_CurrentChanged);
            }
        }

        private void buttonSave_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                _context.SaveChanges();
                this.Close();
                
            }
            catch (Exception err)
            {
                MessageBox.Show("Error saving changes\n" + err.Message, "Error!");
            }
        }

        private void buttonCancel_Click(object sender, RoutedEventArgs e)
        {
            this.Close();
        }

        private void btnAddToPlan_Click(object sender, RoutedEventArgs e)
        {
            int productGroupID = (int)comboProductGroup.SelectedValue;
            tblProduct selectedProduct = (tblProduct)listViewProducts.SelectedItem;
            var containsProductList = (from c in _context.tblProduct
                                      where (bool)c.ActiveItem
                                        && c.ProductID != selectedProduct.ProductID
                                        && !c.ContainedIn.Any(ci => ci.ProductID == selectedProduct.ProductID)
                                        && !c.Includes.Any(ci=> ci.ProductID == selectedProduct.ProductID)
                                      orderby c.ItemCode
                                       select new { c.ProductID, c.ShortName, c.ItemCode, c.LongName }).ToArray();

            ProductList dlg = new ProductList(containsProductList.AsQueryable());
            if ((bool)dlg.ShowDialog())
            {
                //tblProductComponent newComponent = (tblProductComponent)((IEditableCollectionView)_productComponentViewSource.View).AddNew();
                tblProductComponent newComponent = new tblProductComponent();
                newComponent.Qty = 1;
                newComponent.Product = selectedProduct;
                newComponent.ComponentProduct = (tblProduct)_context.GetObjectByKey(new System.Data.EntityKey("SalesManagerEntities.tblProduct", "ProductID", dlg.ProductID));
                _context.AddTotblProductComponent(newComponent);
                //((IEditableCollectionView)_productComponentViewSource.View).CommitNew();
            }
        }

        private void btnRemoveFromPlan_Click(object sender, RoutedEventArgs e)
        {
            _context.DeleteObject((tblProductComponent)gridBuildPlan.SelectedItem);
        }

        private void btnIntentoryHistory_Click(object sender, RoutedEventArgs e)
        {
            // Get the selected inventory
            tblInventory inventory = (tblInventory)gridInventory.SelectedItem;

            dlgIntentoryHistory dlg = new dlgIntentoryHistory(_context, inventory);
            dlg.ShowDialog();
        }

        private void AddLocation_Click(object sender, RoutedEventArgs e)
        {
            tblProduct product = (tblProduct)_productViewSource.View.CurrentItem;
            if (product.InventoryItem)
            {
                tblLocation location = (tblLocation)_productInventoryUnmappedLocations.View.CurrentItem;
                tblInventory newInventory = new tblInventory();
                newInventory.Product = product;
                newInventory.Qty = 0;
                newInventory.tblLocation = location;
                _context.AddTotblInventory(newInventory);
            }
            else
                MessageBox.Show("This item is not marked as being an inventory item");
        }

        private void btnAdjustInventory_Click(object sender, RoutedEventArgs e)
        {
            if (_context.ObjectStateManager.GetObjectStateEntries(System.Data.EntityState.Added | System.Data.EntityState.Deleted | System.Data.EntityState.Modified).Count() > 0)
            {
                if (MessageBox.Show("Pending changes must be saved prior to adjusting inventory.  Do you want to save changes?", "Save Changes", MessageBoxButton.YesNo) != MessageBoxResult.Yes)
                    return;
            }

            // Get the selected inventory
            tblInventory inventory = (tblInventory)gridInventory.SelectedItem;

            // We need to save changes before and after inventory
            _context.SaveChanges();
            dlgAdjustInventory dlg = new dlgAdjustInventory(_context, inventory);
            dlg.ShowDialog();
            _context.Refresh(System.Data.Objects.RefreshMode.StoreWins, inventory);
            foreach (qryInventoryLevels q in (System.Data.Objects.ObjectQuery<qryInventoryLevels>)_detailViewSource.Source)
                _context.Refresh(System.Data.Objects.RefreshMode.StoreWins, q);
            //_context.Refresh(System.Data.Objects.RefreshMode.StoreWins, _detailViewSource.Source);
            //_detailViewSource.Source = (from c in _context.qryInventoryLevels
            //                            where c.InventoryID == inventory.InventoryID
            //                            select c);
            //gridInventory_RowDetailsVisibilityChanged(gridInventory, 
            //    new Microsoft.Windows.Controls.DataGridRowDetailsEventArgs( ,
            //        ));
        }

        private void InventoryTransaction_Filter(object sender, FilterEventArgs e)
        {
            e.Accepted = !"CX".Contains(((tblInventoryTransaction)e.Item).InventoryTransactionStatusCode);
        }

        private void gridInventory_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
        }

        private void btnAdd_Click(object sender, RoutedEventArgs e)
        {
            IEditableCollectionView repositoryView = (IEditableCollectionView)_productViewSource.View;
            // This code gets around thb problem with adding to an empty view.
            if (!repositoryView.CanAddNew)
            {
                ConstructorInfo ci = typeof(tblProduct).GetConstructor(new Type[] { });
                FieldInfo field = repositoryView.GetType().GetField("_itemConstructor", BindingFlags.Instance | BindingFlags.NonPublic);
                field.SetValue(repositoryView, ci);
            }

            tblProduct newProduct = (tblProduct)repositoryView.AddNew();
            newProduct.Owner = (tblOwner)_context.GetObjectByKey(new System.Data.EntityKey("SalesManagerEntities.tblOwner", "OwnerID", OwnerID));
            newProduct.ItemCode = "NewItem";
            int productGroupID = (int)comboProductGroup.SelectedValue;
            newProduct.ProductGroup = (tblProductGroup)_context.GetObjectByKey(new System.Data.EntityKey("SalesManagerEntities.tblProductGroup", "ProductGroupID", productGroupID));

            ((IEditableCollectionView)_productViewSource.View).CommitNew();
            _productViewSource.View.MoveCurrentTo(newProduct);

            tabPanel1.SelectedIndex = 0;
            txtItemCode.Focus();
            txtItemCode.SelectAll();
        }

        private void gridInventory_RowDetailsVisibilityChanged(object sender, DataGridRowDetailsEventArgs e)
        {
            Grid grid = (Grid)e.DetailsElement;
            tblInventory selectedInventory = (tblInventory)_productInventory.View.CurrentItem;
            _detailViewSource.Source = (from c in _context.qryInventoryLevels
                     where c.InventoryID == selectedInventory.InventoryID
                     select c);

            grid.DataContext = _detailViewSource;
        }

        private void RadioButton_Checked(object sender, RoutedEventArgs e)
        {
            if (listViewProducts != null)
                if ((bool)rbShortName.IsChecked)
                    listViewProducts.DisplayMemberPath = "ShortName";
                else
                    listViewProducts.DisplayMemberPath = "ItemCode";
            if (_productViewSource != null)
            {
                _productViewSource.SortDescriptions.Clear();
                _productViewSource.SortDescriptions.Add(new SortDescription(listViewProducts.DisplayMemberPath, ListSortDirection.Ascending));
            }
        }

        private void menuProductGroups_Click(object sender, RoutedEventArgs e)
        {
            dlgProductGroups dlg = new dlgProductGroups(_context, OwnerID);
            dlg.ShowDialog();

            _productGroupViewSource.Source = from c in _context.tblProductGroup
                                                 .Include("Products.ProductComponents.ComponentProduct")
                                                 .Include("Products.ProductPricing")
                                             where c.Active
                                                && c.Owner.OwnerID == OwnerID
                                             orderby c.ShortName
                                             select c;
        }

        private void btnDeleteOrderSource_Click(object sender, RoutedEventArgs e)
        {
            tblProductOrderSource productOrderSource = (tblProductOrderSource)((Button)e.Source).CommandParameter;
            _context.DeleteObject(productOrderSource);
        }

        private void btnAddOrderSource_Click(object sender, RoutedEventArgs e)
        {
            //tblProductOrderSource.tblProductOrderSource newOrderSource = (tblProductOrderSource)((IEditableCollectionView)_productOrderSourceViewSource.View).AddNew();
            tblProductOrderSource newOrderSource = new tblProductOrderSource();
            newOrderSource.OrderSource = (tblOrderSource)cmbOrderSource.SelectedItem;
            newOrderSource.Product = (tblProduct)_productViewSource.View.CurrentItem;
            _context.AddTotblProductOrderSource(newOrderSource);
            //((IEditableCollectionView)_productOrderSourceViewSource.View).CommitNew();
        }

        private void chkFilterActive_Checked(object sender, RoutedEventArgs e)
        {
            ProductGroup_CurrentChanged(null, null);
        }

    }

}
